﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

using alib;
using alib.Debugging;
using alib.String;
using alib.Enumerable;
using alib.Collections;
using alib.Collections.ReadOnly;
using alib.Dictionary;
using alib.BitArray;
using alib.Memory;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	[StructLayout(LayoutKind.Explicit)]
	public struct arr_tfs_entry : IComparable<arr_tfs_entry>
	{
		static arr_tfs_entry() { None = Collection<arr_tfs_entry>.None; }
		public static readonly arr_tfs_entry[] None;

		public arr_tfs_entry(int i_feat, int mark, Edge.Flag e_FlagsId, int e_Mark)
			: this()
		{
			this.i_feat = (short)i_feat;
			this.mark = (short)mark;
			this.e_FlagsId = e_FlagsId;
			this.e_Mark = e_Mark;
		}
		public arr_tfs_entry(FeatMark fm, Edge e)
			: this(fm.i_feat, fm.m, e.FlagsId, e.Mark)
		{
		}
		public arr_tfs_entry(int i_feat, int mark, Edge e)
			: this(i_feat, mark, e.FlagsId, e.Mark)
		{
		}

		[FieldOffset(0), DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int hash_code;
		[FieldOffset(0)]
		public short i_feat;
		[FieldOffset(2)]
		public short mark;

		[FieldOffset(4), DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int _next32;

		[FieldOffset(4), DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public transfer.old.TaggedRelMode tgrm;
		[FieldOffset(6)]
		public ushort next;

		[FieldOffset(8), DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public ulong e_ul;
		[FieldOffset(8)]
		public Edge e;
		[FieldOffset(8)]
		public Edge.Flag e_FlagsId;		// 8
		[FieldOffset(12)]
		public int e_Mark;				// 12

		public void SetRaw(int i_feat, int mark, Edge e)
		{
			this.i_feat = (short)i_feat;
			this.mark = (short)mark;
			this.e = e;
		}

		public transfer.old.RootNodeData rnd
		{
			get { return new transfer.old.RootNodeData(tgrm, e); }
			set
			{
				this.tgrm = value.tgrm;
				this.e = value.e;
			}
		}

		public FeatMark FeatMark
		{
			get { return new FeatMark(i_feat, mark); }
			set
			{
				this.i_feat = (short)value.i_feat;
				this.mark = (short)value.m;
			}
		}

		public int CompareTo(arr_tfs_entry other)
		{
			int d = mark - other.mark;
			return d != 0 ? d : i_feat - other.i_feat;
		}

		public override bool Equals(object obj) { throw new Exception(); }
		public override int GetHashCode() { throw new Exception(); }

#if DEBUG
		public String ToString(FeatMgr ftm)
		{
			String f;
			String nxt = "";// next == -1 ? "" : next.ToString("0000");
			if (ftm == null || i_feat >= ftm.Count || (f = ftm[i_feat].feature) == null)
				return String.Format("{0} {1} {2} {3}", i_feat, mark, e.ToString(), nxt);
			String s = mark + "/" + f.ToUpper();
			return String.Format("{0,20} {1,30} {2}", s, e, nxt);
		}
#endif
	};
}